package com.memory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.memory.common.R;
import com.memory.dao.DishDao;
import com.memory.dao.DishFlavorDao;
import com.memory.daomain.Category;
import com.memory.daomain.Dish;
import com.memory.daomain.DishFlavor;
import com.memory.dto.DishDto;
import com.memory.service.CategoryService;
import com.memory.service.DishFlavorService;
import com.memory.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 邓哈哈
 * 2023/1/16 14:43
 * Function:
 * Version 1.0
 */
@Slf4j
@Service
public class DishServiceImpl extends ServiceImpl<DishDao, Dish> implements DishService {
    @Autowired
    private DishDao dishDao;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;


    /**
     * 添加菜品
     * 同时保存对应的菜品口味数据
     * 同时操作两张表
     *
     * @return
     */
    @Transactional
    @Override
    public Boolean saveDishWithFlavor(DishDto dishDto) {
        //添加菜品(保存菜品的基本信息)
        boolean save = this.save(dishDto);

        //保存对应的菜品口味数据
        //1.获取菜品口味数据
        List<DishFlavor> flavors = dishDto.getFlavors();
        //2.获取该菜品的id
        Long dishId = dishDto.getId();
        //3.给该菜品的每道口味添加菜品id信息
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());
        //4.保存菜品口味
        boolean saveBatch = dishFlavorService.saveBatch(flavors);

        return save && saveBatch;//当菜品和对应菜品口味都成功添加后,返回成功
    }

    /**
     * 删除菜品
     * 删除菜品对应口味
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public Boolean delete(Long ids) {
        //删除菜品信息
        boolean remove = this.removeById(ids);

        //删除对应口味信息
        LambdaQueryWrapper<DishFlavor> lqw = new LambdaQueryWrapper<>();
        //设置删除条件
        lqw.eq(ids != null, DishFlavor::getDishId, ids);
        //执行删除
        boolean removeBatch = dishFlavorService.remove(lqw);

        return remove && removeBatch;
    }

    /**
     * 更新菜品
     * 同时更新对应的菜品口味数据
     * 同时操作两张表
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public Boolean updateDishWithFlavor(DishDto dishDto) {
        //修改菜品信息
        boolean update = this.updateById(dishDto);

        //修改菜品对应口味信息
        //1.首先删除所有对应口味信息
        LambdaQueryWrapper<DishFlavor> lqw = new LambdaQueryWrapper<>();
        //获取DishId
        Long dishId = dishDto.getId();
        //2.设置查询条件
        lqw.eq(dishDto != null, DishFlavor::getDishId, dishId);
        //3.执行删除
        dishFlavorService.remove(lqw);

        //添加更新后的口味信息
        //1.获取要添加的口味信息
        List<DishFlavor> flavors = dishDto.getFlavors();
        //2.给该菜品的每道口味添加菜品id信息
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());
        //执行添加
        boolean saveBatch = dishFlavorService.saveBatch(flavors);

        return update && saveBatch;//当菜品和对应菜品口味都成功更新后,返回成功
    }

    /**
     * 回显菜品
     * 回显口味
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DishDto getById(Long id) {
        //根据id查询对应菜品信息
        Dish dish = dishDao.selectById(id);
//        Dish byId = this.getById(id);

        //根据DishId查询菜品对应菜品口味信息
        LambdaQueryWrapper<DishFlavor> lqw = new LambdaQueryWrapper<>();
        //根据DishId和id是否一致,条件查询
        lqw.eq(id != null, DishFlavor::getDishId, id);
        //进行条件查询
        List<DishFlavor> dishFlavors = dishFlavorService.list(lqw);

        //将查询到的菜品和对应菜品口味封装成DishDto类
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);//对象拷贝
        dishDto.setFlavors(dishFlavors);//设置flavors的值

        return dishDto;
    }

    /**
     * 分页查询
     * 条件查询
     *
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public Page<DishDto> getPage(Integer page, Integer pageSize, Dish dish) {
        //1.封装Page类
        Page<Dish> dishPage = new Page<>(page, pageSize);
        Page<DishDto> dishDtoPage = new Page<>(page, pageSize);

        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //2.设置查询条件
        lqw.like(dish.getName() != null, Dish::getName, dish.getName());

        //3.执行分页查询
        dishDao.selectPage(dishPage, lqw);

        log.info("records =>{}", dishPage.getRecords());

        //显示菜品所属菜品种类的思路:封装DishDto,拷贝Dish,同时设置categoryName
        //1.封装dishDto,拷贝每个dish
        BeanUtils.copyProperties(dishPage, dishDtoPage);

        //2.拿取每个Dish
        List<Dish> records = dishPage.getRecords();

        //3.把给每个Dish封装成DishDto,设置categoryName
        List<DishDto> dtoList = records.stream().map((item) -> {
            //拿取菜品categoryId
            Long categoryId = item.getCategoryId();

            //根据categoryId查询对应菜品分类
            LambdaQueryWrapper<Category> category_lqw = new LambdaQueryWrapper<>();
            category_lqw.eq(categoryId != null, Category::getId, categoryId);//设置查询条件
            Category category = categoryService.getOne(category_lqw);//执行查询

            //将菜品分类的name设置为该DishDto的categoryName
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            dishDto.setCategoryName(category.getName());

            return dishDto;
        }).collect(Collectors.toList());

//        for (DishDto record : records) {
//            Long categoryId = record.getCategoryId();
//            log.info("categoryId=>{}", categoryId);
//        }

        dishDtoPage.setRecords(dtoList);

        return dishDtoPage;
    }

    /**
     * 菜品展示
     *
     * @param dish
     * @return
     */
    @Override
    public List<DishDto> list(Dish dish) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //构造查询条件
        //1.查询当前菜品分类下的菜品信息
        lqw.eq(dish != null, Dish::getCategoryId, dish.getCategoryId());

        //2.查询正在启售的菜品(状态为1的菜品)
        lqw.eq(Dish::getStatus, 1);

        //构造排序条件
        lqw.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);//按sort升序排列,按updateTime降序排列

        List<Dish> dishList = this.list(lqw);

        //2.拿取每个Dish,把给每个Dish封装成DishDto,设置categoryName
        List<DishDto> dishDtoList = dishList.stream().map((item) -> {
            //拿取菜品id
            Long dishId = item.getId();

            //根据菜品id查询对应口味
            LambdaQueryWrapper<DishFlavor> dishFlavor_lqw = new LambdaQueryWrapper<>();
            dishFlavor_lqw.eq(dishId != null, DishFlavor::getDishId, dishId);
            List<DishFlavor> dishFlavorList = dishFlavorService.list(dishFlavor_lqw);

            //查询该菜品对应菜品口味
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);

            dishDto.setFlavors(dishFlavorList);

            return dishDto;
        }).collect(Collectors.toList());

        return dishDtoList;
    }

}
